package navigation

import (
	"context"

	"BookStack/internal/domain/events"
	"BookStack/internal/domain/navigation"
	"BookStack/pkg/utils"
)

// 定义事件类型
const (
	NavigationCreatedEventType = "navigation.created"
	NavigationUpdatedEventType = "navigation.updated"
	NavigationDeletedEventType = "navigation.deleted"
)

// Service 导航应用服务接口
type Service interface {
	// ListNavigations 获取导航列表
	ListNavigations(ctx context.Context, position string, page, pageSize int, status *int) (*NavigationListResponse, error)

	// GetNavigation 获取导航详情
	GetNavigation(ctx context.Context, id uint) (*NavigationResponse, error)

	// CreateNavigation 创建导航
	CreateNavigation(ctx context.Context, req *CreateNavigationRequest) (*NavigationResponse, error)

	// UpdateNavigation 更新导航
	UpdateNavigation(ctx context.Context, req *UpdateNavigationRequest) (*NavigationResponse, error)

	// DeleteNavigation 删除导航
	DeleteNavigation(ctx context.Context, id uint) error
}

// service 导航应用服务实现
type service struct {
	navigationService navigation.Service
	eventPublisher    events.Publisher
}

// NewService 创建导航应用服务
func NewService(navigationService navigation.Service, eventPublisher events.Publisher) Service {
	return &service{
		navigationService: navigationService,
		eventPublisher:    eventPublisher,
	}
}

// ListNavigations 获取导航列表
func (s *service) ListNavigations(ctx context.Context, position string, page, pageSize int, status *int) (*NavigationListResponse, error) {
	// 调用领域服务获取导航列表
	navigations, total, err := s.navigationService.List(ctx, page, pageSize, position, status)
	if err != nil {
		return nil, WrapError(err)
	}

	// 转换为响应
	result := &NavigationListResponse{
		Total: total,
		Items: make([]*NavigationResponse, 0, len(navigations)),
	}

	for _, nav := range navigations {
		result.Items = append(result.Items, &NavigationResponse{
			ID:          nav.ID,
			Name:        nav.Name,
			URL:         nav.URL,
			Icon:        nav.Icon,
			Position:    nav.Position,
			ParentID:    nav.ParentID,
			Order:       nav.Order,
			Status:      nav.Status,
			Target:      nav.Target,
			Description: nav.Description,
			CreatedAt:   nav.CreatedAt,
			UpdatedAt:   nav.UpdatedAt,
		})
	}

	return result, nil
}

// GetNavigation 获取导航详情
func (s *service) GetNavigation(ctx context.Context, id uint) (*NavigationResponse, error) {
	// 调用领域服务获取导航
	nav, err := s.navigationService.GetByID(ctx, id)
	if err != nil {
		return nil, WrapError(err)
	}

	// 转换为响应
	return &NavigationResponse{
		ID:          nav.ID,
		Name:        nav.Name,
		URL:         nav.URL,
		Icon:        nav.Icon,
		Position:    nav.Position,
		ParentID:    nav.ParentID,
		Order:       nav.Order,
		Status:      nav.Status,
		Target:      nav.Target,
		Description: nav.Description,
		CreatedAt:   nav.CreatedAt,
		UpdatedAt:   nav.UpdatedAt,
	}, nil
}

// CreateNavigation 创建导航
func (s *service) CreateNavigation(ctx context.Context, req *CreateNavigationRequest) (*NavigationResponse, error) {
	// 调用领域服务创建导航
	var parentID uint
	if req.ParentID != nil {
		parentID = *req.ParentID
	}

	params := &navigation.CreateNavigationParams{
		Name:        req.Name,
		URL:         req.URL,
		Icon:        req.Icon,
		Position:    req.Position,
		ParentID:    parentID,
		Order:       req.Order,
		Status:      req.Status,
		Target:      req.Target,
		Description: req.Description,
	}

	nav, err := s.navigationService.Create(ctx, params)
	if err != nil {
		return nil, WrapError(err)
	}

	// 发布事件
	event := &events.NavigationCreatedEvent{
		ID:        nav.ID,
		Name:      nav.Name,
		Position:  nav.Position,
		CreatedAt: utils.TimeToJSONTime(nav.CreatedAt),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.NavigationCreatedEventType, event))

	// 转换为响应
	return &NavigationResponse{
		ID:          nav.ID,
		Name:        nav.Name,
		URL:         nav.URL,
		Icon:        nav.Icon,
		Position:    nav.Position,
		ParentID:    nav.ParentID,
		Order:       nav.Order,
		Status:      nav.Status,
		Target:      nav.Target,
		Description: nav.Description,
		CreatedAt:   nav.CreatedAt,
		UpdatedAt:   nav.UpdatedAt,
	}, nil
}

// UpdateNavigation 更新导航
func (s *service) UpdateNavigation(ctx context.Context, req *UpdateNavigationRequest) (*NavigationResponse, error) {
	// 调用领域服务更新导航
	var parentID uint
	if req.ParentID != nil {
		parentID = *req.ParentID
	}

	params := &navigation.UpdateNavigationParams{
		ID:          req.ID,
		Name:        req.Name,
		URL:         req.URL,
		Icon:        req.Icon,
		Position:    req.Position,
		ParentID:    parentID,
		Order:       req.Order,
		Status:      req.Status,
		Target:      req.Target,
		Description: req.Description,
	}

	nav, err := s.navigationService.Update(ctx, params)
	if err != nil {
		return nil, WrapError(err)
	}

	// 发布事件
	event := &events.NavigationUpdatedEvent{
		ID:        nav.ID,
		Name:      nav.Name,
		Position:  nav.Position,
		UpdatedAt: utils.TimeToJSONTime(nav.UpdatedAt),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.NavigationUpdatedEventType, event))

	// 转换为响应
	return &NavigationResponse{
		ID:          nav.ID,
		Name:        nav.Name,
		URL:         nav.URL,
		Icon:        nav.Icon,
		Position:    nav.Position,
		ParentID:    nav.ParentID,
		Order:       nav.Order,
		Status:      nav.Status,
		Target:      nav.Target,
		Description: nav.Description,
		CreatedAt:   nav.CreatedAt,
		UpdatedAt:   nav.UpdatedAt,
	}, nil
}

// DeleteNavigation 删除导航
func (s *service) DeleteNavigation(ctx context.Context, id uint) error {
	// 获取导航信息用于事件
	nav, err := s.navigationService.GetByID(ctx, id)
	if err != nil {
		return WrapError(err)
	}

	// 调用领域服务删除导航
	if err := s.navigationService.Delete(ctx, id); err != nil {
		return WrapError(err)
	}

	// 发布事件
	event := &events.NavigationDeletedEvent{
		ID:       nav.ID,
		Name:     nav.Name,
		Position: nav.Position,
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.NavigationDeletedEventType, event))

	return nil
}

// isValidPosition 检查导航位置是否有效
func isValidPosition(position string) bool {
	return position == navigation.PositionHeader ||
		position == navigation.PositionFooter ||
		position == navigation.PositionMobile
}

// getPositionName 获取导航位置的中文名称
func getPositionName(position string) string {
	switch position {
	case navigation.PositionHeader:
		return "头部导航"
	case navigation.PositionFooter:
		return "底部导航"
	case navigation.PositionMobile:
		return "移动端导航"
	default:
		return position
	}
}
